package com.shell.governor.modules.service.impl;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.shell.bee.base.utils.StringUtil;
import com.shell.bee.base.utils.SystemUtil;
import com.shell.bee.entity.mvc.RetMsg;
import com.shell.bee.persistence.service.impl.PersistentServiceImpl;
import com.shell.framework.utils.CommonDataUtil;
import com.shell.framework.utils.SysDateUtil;
import com.shell.governor.modules.dao.PubDictionaryDao;
import com.shell.governor.modules.po.PubDictionary;
import com.shell.governor.modules.service.PubDictionaryService;

import tk.mybatis.mapper.entity.Example;

@Service
public class PubDictionaryServiceImpl extends PersistentServiceImpl<PubDictionary> implements PubDictionaryService {
	@Autowired
	PubDictionaryDao pubDictionaryDao;

	public int saveOrUpdateDictionary(PubDictionary dic) {
		if (StringUtil.notTrimEmpty(dic.getDicId())) {
			dic.setEditorId(CommonDataUtil.getUserId());
			dic.setCreateTime(SysDateUtil.getSystemDateTime());
			return updateAll(dic);
		}
		dic.setDicId(SystemUtil.getUUID());
		dic.setDicPath(dic.getDicPath() + ',' + dic.getDicId());
		dic.setCreateTime(SysDateUtil.getSystemDateTime());
		dic.setCreatorId(CommonDataUtil.getUserId());
		return save(dic);
	}

	public boolean checkCodeUnique(PubDictionary entity) {
		if (StringUtil.trimEmpty(entity.getDicCode())) {
			return true;
		}
		Example example = new Example(PubDictionary.class);
		Example.Criteria criteria = example.createCriteria();
		if (!StringUtil.trimEmpty(entity.getDicId())) {
			criteria.andNotEqualTo("dicId", entity.getDicId());
		}
		criteria.andEqualTo("dicCode", entity.getDicCode());
		criteria.andNotEqualTo("dicState", "D");

		List<PubDictionary> list = selectByExample(example);
		if (list.size() > 0) {
			return false;
		}
		return true;
	}

	public RetMsg setDictionaryStatusWithCascade(PubDictionary dictionary) {
		dictionary.setDicId("%" + dictionary.getDicId() + "%");

		int update_count = this.pubDictionaryDao.setDictionaryStatusWithCascade(dictionary);
		if (update_count > 0) {
			return new RetMsg("success", "������������");
		}
		return new RetMsg("error", "��������������");
	}

	public List<PubDictionary> getAllDicTreeList(PubDictionary dictionary) {
		if ((dictionary != null) && (!StringUtil.emptyAndNull(dictionary.getDicName()))) {
			dictionary.setDicName(StringUtil.getParameterLike(dictionary.getDicName()));
		}
		if ((dictionary != null) && (!StringUtil.emptyAndNull(dictionary.getDicCode()))) {
			PubDictionary dic = new PubDictionary();
			dic.setDicCode(dictionary.getDicCode());
			dic = (PubDictionary) this.pubDictionaryDao.selectOne(dic);
			dictionary.setDicPath(StringUtil.getParameterLike(dic.getDicId()));
		}
		List<PubDictionary> dictionarys = this.pubDictionaryDao.selectDictionaryTree(dictionary);
		for (PubDictionary dic : dictionarys) {
			if (!StringUtil.emptyAndNull(dic.getDicPath())) {
				String[] id = dic.getDicPath().split(",");
				String parentName = "";
				if (id.length > 2) {
					for (int i = 1; i < id.length; i++) {
						PubDictionary parentDic = (PubDictionary) this.pubDictionaryDao.selectByPrimaryKey(id[i]);
						parentName = parentName + parentDic.getDicName() + "_";
					}
				}
				dic.setParentName(parentName);
			}
		}
		List<PubDictionary> dicTreeList = new ArrayList<PubDictionary>();
		genDictionaryTree(dictionarys, dicTreeList, 0, 0);
		return dicTreeList;
	}

	private int genDictionaryTree(List<PubDictionary> dictionarys, List<PubDictionary> children, int start, int level) {
		int index = start;
		while (index < dictionarys.size()) {
			PubDictionary dic = (PubDictionary) dictionarys.get(index);
			if (dic.getDicLevel().intValue() == level) {
				children.add(dic);
				dic.setChildren(new ArrayList<PubDictionary>());
				index = genDictionaryTree(dictionarys, dic.getChildren(), index + 1, level + 1);
			} else {
				if (dic.getDicLevel().intValue() < level) {
					break;
				}
				if (dic.getDicLevel().intValue() > level) {
					index = genDictionaryTree(dictionarys, children, index, dic.getDicLevel().intValue());
				}
			}
		}
		if (children.size() > 0) {
			Collections.sort(children, new Comparator<PubDictionary>() {
				@Override
				public int compare(PubDictionary arg0, PubDictionary arg1) {
					if ((arg0.getDicSort() == null) && (arg1.getDicSort() == null)) {
						return 0;
					}
					if (arg0.getDicSort() == null) {
						return 1;
					}
					if (arg1.getDicSort() == null) {
						return -1;
					}
					return arg0.getDicSort().compareTo(arg1.getDicSort());
				}
			});
		}
		return index;
	}

	public PubDictionary findDictionaryByDicId(String dicId) {
		PubDictionary dic = (PubDictionary) selectByKey(dicId);
		if ((dic.getDicLevel().intValue() > 0) && (!StringUtil.emptyAndNull(dic.getParentId()))) {
			dic.setParentName(((PubDictionary) selectByKey(dic.getParentId())).getDicName());
		}
		return dic;
	}

	public int updateResourceStateWithCascade(String dicId, String parentId, String state) {
		int result = this.pubDictionaryDao.updateDictionaryStateWithCascade("%" + dicId + "%", state);
		if ((result > 0) && (StringUtil.notEmpty(parentId)) && (state.equals("E"))) {
			Example example = new Example(PubDictionary.class);
			Example.Criteria criteria = example.createCriteria();
			criteria.andEqualTo("parentId", parentId);
			criteria.andNotEqualTo("dicState", "D");
			criteria.andEqualTo("dicState", "E");
			List<PubDictionary> list = selectByExample(example);
			if (list.size() > 0) {
				PubDictionary pd = new PubDictionary();
				pd.setDicId(parentId);
				pd.setDicState("E");
				this.pubDictionaryDao.updateByPrimaryKeySelective(pd);
			}
		}
		return result;
	}

	public Map<String, PubDictionary> getDicMap() {
		List<PubDictionary> dics = getAllDicTreeList(null);
		Map<String, PubDictionary> map = new HashMap<String, PubDictionary>();
		genDicMap(dics, map);
		return map;
	}

	private void genDicMap(List<PubDictionary> dics, Map<String, PubDictionary> map) {
		if (dics != null) {
			for (PubDictionary dic : dics) {
				map.put(dic.getDicCode(), dic);
				if ((dic.getChildren() != null) && (dic.getChildren().size() > 0)) {
					genDicMap(dic.getChildren(), map);
				}
			}
		}
	}

	public PubDictionary getDictionaryByCode(String code) {
		PubDictionary dict = new PubDictionary();
		dict.setDicCode(code);
		return (PubDictionary) this.pubDictionaryDao.selectOne(dict);
	}

	public List<PubDictionary> selectChildDictByParentCode(String parentCode) {
		return this.pubDictionaryDao.selectChildDictByParentCode(parentCode);
	}
}
